"""
@author: 江同学呀
@file:  hits.py
@date: 2025/3/15 12:55
@desc: 
    
"""
from typing import Dict, Literal, Union, Iterable

from espc.common.common import Number
from espc.orm.model.base.base import _Base
from espc.orm.model.mapping.field.base_field.base_field import _BaseField


class Hits(_Base):
    """

    (object) Contains returned documents and metadata.
    （对象）包含返回的文档和元数据。

    :param total:
        (object) Metadata about the number of returned documents.
        Properties of total

            value
                (integer) Total number of returned documents.
            relation
                (string) Indicates whether the number of returned documents in the value parameter is accurate or a
                lower bound.
        Values of relation:
            eq
                Accurate
            gte
                Lower bound, including returned documents

        （对象）有关返回文档数量的元数据。
        total 的属性
            value
                （整数）返回的文档总数。
            relation
                （字符串）指示 value 参数中返回的文档数是准确的还是下限。
        关系的值：
            eq
                Accurate
            gte
                下限，包括返回的文档
    :param max_score:
        (float) Highest returned document _score.
        This value is null for requests that do not sort by _score.

        （浮点型）最高返回的文档_score。
        对于不按 _score 排序的请求，此值为 null。
    :param hits:
        (array of objects) Array of returned document objects.
        Properties of hits objects
            _index
                (string) Name of the index containing the returned document.
            _type
                [6.0.0] Deprecated in 6.0.0. Mapping types are deprecated and will be removed in 8.0. See Removal of
                mapping types.(string) Mapping type of the returned document.
            _id
                (string) Unique identifier for the returned document. This ID is only unique within the returned index.
            _score
                (float) Positive 32-bit floating point number used to determine the relevance of the returned document.
            _source
                (object) Original JSON body passed for the document at index time.
                You can use the _source parameter to exclude this property from the response or specify which source
                fields to return.
            fields
                (object) Contains field values for the documents. These fields must be specified in the request using
                one or more of the following request parameters:
                    - docvalue_fields
                    - script_fields
                    - stored_fields
                This property is returned only if one or more of these parameters are set.
                Properties of fields
                    <field>
                        (array) Key is the field name. Value is the value for the field.

        （对象数组）返回的 document 对象的数组。
        命中对象的属性
            _index
                （字符串）包含返回文档的索引的名称。
            _type
                (string) 返回文档的映射类型。
            _id
                （字符串）返回的文档的唯一标识符。此 ID 仅在返回的索引中是唯一的。
            _score
                （浮点型）用于确定返回文档的相关性的 32 位正浮点数。
            _source
                （对象）在索引时为文档传递的原始 JSON 正文。
                您可以使用 _source 参数从响应中排除此属性，或指定要返回的源字段。
            fields
                （对象）包含文档的字段值。必须使用以下一个或多个请求参数在请求中指定这些字段：
                    - docvalue_fields
                    - script_fields
                    - stored_fields
                仅当设置了这些参数中的一个或多个时，才会返回此属性。
                字段的属性
                    <field>
                        （数组）Key 是字段名称。Value 是字段的值。
    """
    def __init__(
            self, total: Dict[Literal["value", "relation"], Union[int, str]] = None, max_score: Number = None,
            hits: Dict[
                Literal["_index", "_type", "_id", "_score", "_source", "fields"],
                Union[str, Number, Dict, Iterable[_BaseField]]
            ] = None
    ):
        super().__init__()
        self.total: Dict[Literal["value", "relation"], Union[int, str]] = total
        self.max_score: Number = max_score
        self.hits: Dict[
            Literal["_index", "_type", "_id", "_score", "_source", "fields"],
            Union[str, Number, Dict, Iterable[Union[_BaseField, str]]]
        ] = hits
        return

    def _build(self) -> Dict:
        _body: Dict = {}
        if self.total:
            _body["total"] = self.total
        if self.max_score is not None:
            _body["max_score"] = self.max_score
        if self.hits:
            _body["hits"] = {
                k: (
                    v
                    if isinstance(v, (str, Number, Dict))
                    else [
                        i._field_name if isinstance(i, _BaseField) else v
                        for i in v
                    ]
                )
                for k, v in self.hits.items()
            }
        return _body
